home *** CD-ROM | disk | FTP | other *** search
- #ifdef INCRCy( pdriv, GÃr RCSid[]="$Id: print.c,v 1.3 1998/12/17 22:10:44 lhecking Exp $" ;
- #endif
-
- /****************************************************************************
-
- PROGRAM: gnupmdrv
-
- Outboard PM driver for GNUPLOT 3.3
-
- MODULE: print.c -- support for printing graphics under OS/2
-
- ****************************************************************************/
-
- /* PM driver for GNUPLOT */
-
- /*[
- * Copyright 1992, 1993, 1998 Roger Fearick
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the complete modified source code. Modifications are to
- * be distributed as patches to the released version. Permission to
- * distribute binaries produced by compiling modified sources is granted,
- * provided you
- * 1. distribute the corresponding source modifications from the
- * released version in the form of a patch file along with the binaries,
- * 2. add special version identification to distinguish your version
- * in addition to the base release version number,
- * 3. provide your name and address as the primary contact for the
- * support of your modified version, and
- * 4. retain our contact information in regard to use of the base
- * software.
- * Permission to distribute the released version of the source code along
- * with corresponding source modifications in the form of a patch file is
- * granted with same provisions 2 through 4 for binary distributions.
- *
- * This software is provided "as is" without express or implied warranty
- * to the extent permitted by applicable law.
- ]*/
-
- /*
- * AUTHOR
- *
- * Gnuplot driver for OS/2: Roger Fearick
- *
- * Send your comments or suggestions to
- * info-gnuplot@dartmouth.edu.
- * This is a mailing list; to join it send a note to
- * majordomo@dartmouth.edu.
- * Send bug reports to
- * bug-gnuplot@dartmouth.edu.
- **/
-
- #define INCL_SPLDOSPRINT
- #define INCL_DOSPROCESS
- #define INCL_DOSSEMAPHORES
- #define INCL_DEV
- #define INCL_SPL
- #define INCL_PM
- #define INCL_WIN
- #include <os2.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <process.h>
- #include "gnupmdrv.h"
-
- #define GNUPAGE 4096 /* size of gnuplot page in pixels (driver dependent) */
-
-
- typedef struct { /* for print thread parameters */
- HWND hwnd ;
- HDC hdc ; /* printer device context */
- HPS hps ; /* screen PS to be printed */
- char szPrintFile[256] ; /* file for printer output if not to printer */
- PQPRINT pqp ; /* print queue info */
- } PRINTPARAMS ;
-
- static struct {
- long lTech ; // printer technology
- long lVer ; // driver version
- long lWidth ; // page width in pels
- long lHeight ; // page height in pels
- long lWChars ; // page width in chars
- long lHChars ; // page height in chars
- long lHorRes ; // horizontal resolution pels / metre
- long lVertRes ; // vertical resolution pels / metre
- } prCaps ;
-
- //static PDRIVDATA pdriv = NULL ;
- static DRIVDATA driv = {sizeof( DRIVDATA) } ;
- static char szPrintFile[CCHMAXPATHCOMP] = {0} ;
- static DEVOPENSTRUC devop ;
-
- ULONG GetPrinters( PPRQINFO3 *, ULONG * ) ;
- int FindPrinter( char *, PPRQINFO3 ) ;
- HMF CopyToMetaFile( HPS ) ;
- static void ThreadPrintPage( ) ;
-
- MPARAM PrintCmdProc( HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
- /*
- ** Handle messages for print commands for 1- and 2-d spectra
- ** (i.e for the appropriate 1-and 2-d child windows )
- */
- {
- static BYTE abStack[4096] ;
- static PRINTPARAMS tp ;
- static char szBusy[] = "Busy - try again later" ;
- static char szStart[] = "Printing started" ;
- static HEV semPrint = 0L ;
- static HWND hwndCancel = NULLHANDLE ;
- char szTemp[32] ;
- unsigned short lErr ;
- PBYTE pStack = abStack;
- TID tid ;
- char *pszMess, *szPrinter ;
-
- if( semPrint == 0L ) {
- DosCreateMutexSem( NULL, &semPrint, 0L, 0L ) ;
- }
-
- switch( msg ) {
-
- case WM_USER_PRINT_BEGIN:
-
- if( DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) != 0 ) {
- pszMess = szBusy ;
- WinMessageBox( HWND_DESKTOP,
- hWnd,
- pszMess,
- APP_NAME,
- 0,
- MB_OK | MB_ICONEXCLAMATION ) ;
- }
- else {
- pszMess = szStart ;
- tp.hwnd = hWnd ;
- tp.pqp = (PQPRINT) mp1 ;
- tp.hps = (HPS) mp2 ;
- strcpy( tp.szPrintFile, szPrintFile ) ;
- tid = _beginthread( ThreadPrintPage, NULL, 32768, &tp ) ;
- hwndCancel = WinLoadDlg( HWND_DESKTOP,
- hWnd,
- (PFNWP)CancelPrintDlgProc,
- 0L,
- ID_PRINTSTOP,
- NULL ) ;
- }
- break ;
-
-
- case WM_USER_PRINT_OK :
-
- if( hwndCancel != NULLHANDLE ) {
- WinDismissDlg( hwndCancel, 0 ) ;
- hwndCancel = NULLHANDLE ;
- }
- DosReleaseMutexSem( semPrint ) ;
- break ;
-
- case WM_USER_DEV_ERROR :
-
- if( hwndCancel != NULLHANDLE ) {
- WinDismissDlg( hwndCancel, 0 ) ;
- hwndCancel = NULLHANDLE ;
- }
- lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
- sprintf( szTemp, "Dev error: %d %x", lErr, lErr ) ;
- WinMessageBox( HWND_DESKTOP,
- hWnd,
- szTemp,
- APP_NAME,
- 0,
- MB_OK | MB_ICONEXCLAMATION ) ;
- DosReleaseMutexSem( semPrint ) ;
- break ;
-
- case WM_USER_PRINT_ERROR :
-
- if( hwndCancel != NULLHANDLE ) {
- WinDismissDlg( hwndCancel, 0 ) ;
- hwndCancel = NULLHANDLE ;
- }
- lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
- sprintf( szTemp, "Print error: %d %x", lErr, lErr ) ;
- WinMessageBox( HWND_DESKTOP,
- hWnd,
- szTemp,
- APP_NAME,
- 0,
- MB_OK | MB_ICONEXCLAMATION ) ;
- DosReleaseMutexSem( semPrint ) ;
- break ;
-
- case WM_USER_PRINT_CANCEL :
-
- DevEscape( tp.hdc, DEVESC_ABORTDOC, 0L, NULL, NULL, NULL ) ;
- break ;
-
-
- case WM_USER_PRINT_QBUSY :
-
- return( (MPARAM)DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) ) ;
-
- default : break ;
- }
-
- return 0L ;
- }
-
- int SetupPrinter( HWND hwnd, PQPRINT pqp )
- /*
- ** Set up the printer
- **
- */
- {
- HDC hdc ;
- float flXFrac, flYFrac;
- /* check that printer is still around .. */
- if( FindPrinter( pqp->szPrinterName, pqp->piPrinter ) != 0 ) return 0 ;
- /* get printer capabilities */
- if( (hdc = OpenPrinterDC( WinQueryAnchorBlock( hwnd ), pqp, OD_INFO, NULL )) != DEV_ERROR ) {
- DevQueryCaps( hdc, CAPS_TECHNOLOGY, (long)sizeof(prCaps)/sizeof(long), (PLONG)&prCaps ) ;
- DevCloseDC( hdc ) ;
- pqp->xsize = (float)100.0* (float) prCaps.lWidth / (float) prCaps.lHorRes ; // in cm
- pqp->ysize = (float)100.0* (float) prCaps.lHeight / (float) prCaps.lVertRes ; // in cm
- flXFrac = pqp->xfrac ;
- flYFrac = pqp->yfrac ;
- pqp->szFilename[0] = 0 ;
- szPrintFile[0] = 0 ;
- pqp->caps = prCaps.lTech & (CAPS_TECH_VECTOR_PLOTTER|CAPS_TECH_POSTSCRIPT) ?
- QP_CAPS_FILE : QP_CAPS_NORMAL ;
- if( WinDlgBox( HWND_DESKTOP,
- hwnd,
- (PFNWP)QPrintDlgProc,
- 0L,
- ID_QPRINT,
- pqp ) == DID_OK ) {
- if( pqp->caps & QP_CAPS_FILE ) {
- if( pqp->szFilename[0] != 0 ) strcpy( szPrintFile, pqp->szFilename ) ;
- }
- return 1 ;
- }
- pqp->xfrac = flXFrac ;
- pqp->yfrac = flYFrac ;
- }
-
- return 0 ;
- }
-
- int SetPrinterMode( HWND hwnd, PQPRINT pqp )
- /*
- ** call up printer driver's own setup dialog box
- **
- ** returns : -1 if error
- ** 0 if no settable modes
- ** 1 if OK
- */
- {
- HAB hab ;
- LONG lBytes ;
- PPRQINFO3 pinfo = pqp->piPrinter ;
-
- hab = WinQueryAnchorBlock( hwnd ) ;
- driv.szDeviceName[0]='\0' ;
- lBytes = DevPostDeviceModes( hab,
- NULL,
- devop.pszDriverName,
- pinfo->pDriverData->szDeviceName,
- //driv.szDeviceName,
- NULL,
- DPDM_POSTJOBPROP ) ;
- if( lBytes > 0L ) {
- /* if we have old pdriv data, and if it's for the same printer,
- keep it to retain user's current settings, else get new */
- if( pqp->pdriv != NULL
- && strcmp( pqp->pdriv->szDeviceName, pinfo->pDriverData->szDeviceName ) != 0 ) {
- free( pqp->pdriv ) ;
- pqp->pdriv = NULL ;
- }
- if( pqp->pdriv == NULL ) {
- if( lBytes < pinfo->pDriverData->cb ) lBytes = pinfo->pDriverData->cb ;
- pqp->pdriv = malloc( lBytes ) ;
- pqp->cbpdriv = lBytes ;
- memcpy( pqp->pdriv, pinfo->pDriverData, lBytes ) ;
- }
- strcpy( driv.szDeviceName, pqp->pdriv->szDeviceName ) ;
- // pqp->pdriv->szDeviceName[0] = '\0' ; /* to check if 'cancel' selected */
- lBytes = DevPostDeviceModes( hab,
- pqp->pdriv,
- devop.pszDriverName,
- driv.szDeviceName,
- NULL,
- DPDM_POSTJOBPROP ) ;
- if( lBytes != 1 /*pqp->pdriv->szDeviceName[0] == '\0'*/ ) { /* could be: 'cancel' selected */
- pqp->cbpdriv = lBytes = 0 ;
- free(pqp->pdriv ) ; /* is this right ???? */
- pqp->pdriv = NULL ;
- }
- }
- return ( (int) lBytes ) ;
- }
-
- static void ThreadPrintPage( PRINTPARAMS *ptp )
- /*
- ** thread to set up printer DC and print page
- **
- ** Input: THREADPARAMS *ptp -- pointer to thread data passed by beginthread
- **
- */
- {
- HAB hab ; // thread anchor block nandle
- HDC hdc ; // printer device context handle
- HPS hps ; // presentation space handle
- HDC hdcOld ; // old hdc associated with hps
- SHORT msgRet ; // message posted prior to return (end of thread)
- SIZEL sizPage ; // size of page for creation of presentation space
- LONG alPage[2] ; // actual size of printer page in pixels
- RECTL rectPage ; // viewport on page into which we draw
- LONG lColors ;
- char *szPrintFile ;
- HMF hmf ;
- LONG alOpt[9] ;
- HPS hpsSc ;
- hab = WinInitialize( 0 ) ;
-
- szPrintFile = ptp->szPrintFile[0] == '\0' ? NULL : ptp->szPrintFile ;
-
- if( (hdc = OpenPrinterDC( hab, ptp->pqp, 0L, szPrintFile )) != DEV_ERROR ) {
-
- // create presentation space for printer
-
- ptp->hdc = hdc ;
- hmf = CopyToMetaFile( ptp->hps ) ;
- hpsSc = ptp->hps ;
-
- sizPage.cx = GNUXPAGE;
- sizPage.cy = GNUYPAGE;
- hps = GpiCreatePS( hab,
- hdc,
- &sizPage,
- PU_HIMETRIC | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC ) ;
-
- DevQueryCaps( hdc, CAPS_WIDTH, 2L, alPage ) ;
- DevQueryCaps( hdc, CAPS_PHYS_COLORS, 1L, &lColors ) ;
- rectPage.xLeft = 0L ;
- rectPage.xRight = alPage[0] ;
- rectPage.yTop = alPage[1] ;//alPage[1]*(1.0-flYFrac) ;
- rectPage.yBottom = 0L ; // = alPage[1] ;
-
- {
- double ratio = 1.560 ;
- double xs = rectPage.xRight - rectPage.xLeft ;
- double ys = rectPage.yTop - rectPage.yBottom ;
- if( ys > xs/ratio ) { /* reduce ys to fit */
- rectPage.yTop = rectPage.yBottom + (int)(xs/ratio) ;
- }
- else if( ys < xs/ratio ) { /* reduce xs to fit */
- rectPage.xRight = rectPage.xLeft + (int)(ys*ratio) ;
- }
- }
-
- rectPage.xRight = rectPage.xRight*ptp->pqp->xfrac ;
- rectPage.yTop = rectPage.yTop*ptp->pqp->yfrac ;//alPage[1]*(1.0-flYFrac) ;
-
- {
- double ratio = 1.560 ;
- double xs = rectPage.xRight - rectPage.xLeft ;
- double ys = rectPage.yTop - rectPage.yBottom ;
- if( ys > xs/ratio ) { /* reduce ys to fit */
- rectPage.yTop = rectPage.yBottom + (int)(xs/ratio) ;
- }
- else if( ys < xs/ratio ) { /* reduce xs to fit */
- rectPage.xRight = rectPage.xLeft + (int)(ys*ratio) ;
- }
- }
-
-
- // start printing
-
- if( DevEscape( hdc,
- DEVESC_STARTDOC,
- 7L,
- APP_NAME,
- NULL,
- NULL ) != DEVESC_ERROR ) {
- char buff[256] ;
- int rc;
-
- rc = GpiSetPageViewport( hps, &rectPage ) ;
-
- alOpt[0] = 0L ;
- alOpt[1] = LT_ORIGINALVIEW ;
- alOpt[2] = 0L ;
- alOpt[3] = LC_LOADDISC ;
- alOpt[4] = RES_DEFAULT ;
- alOpt[5] = SUP_DEFAULT ;
- alOpt[6] = CTAB_DEFAULT ;
- alOpt[7] = CREA_DEFAULT ;
- alOpt[8] = DDEF_DEFAULT ;
- if (rc) rc=GpiPlayMetaFile( hps, hmf, 9L, alOpt, NULL, 255, buff ) ;
-
- if (rc) {
- DevEscape( hdc, DEVESC_ENDDOC, 0L, NULL, NULL, NULL ) ;
- msgRet = WM_USER_PRINT_OK ;
- }
- else
- msgRet = WM_USER_PRINT_ERROR;
-
- }
- else
- msgRet = WM_USER_PRINT_ERROR ;
-
- GpiDestroyPS( hps ) ;
- DevCloseDC( hdc ) ;
- }
- else
- msgRet = WM_USER_DEV_ERROR ;
-
- DosEnterCritSec() ;
- WinPostMsg( ptp->hwnd, msgRet, (MPARAM)WinGetLastError(hab), 0L ) ;
- WinTerminate( hab ) ;
- }
-
- HDC OpenPrinterDC( HAB hab, PQPRINT pqp, LONG lMode, char *szPrintFile )
- /*
- ** get printer info from os2.ini and set up DC
- **
- ** Input: HAB hab -- handle of anchor block of printing thread
- ** PQPRINT-- pointer to data of current selected printer
- ** LONG lMode -- mode in which device context is opened = OD_QUEUED, OD_DIRECT, OD_INFO
- ** char *szPrintFile -- name of file for printer output, NULL
- ** if to printer (only used for devices that support file
- ** output eg plotter, postscript)
- **
- ** Return: HDC -- handle of printer device context
- ** = DEV_ERROR (=0) if error
- */
- {
- CHAR *pchDelimiter ;
- LONG lType ;
- static CHAR achPrinterData[256] ;
-
- if( pqp->piPrinter == NULL ) return DEV_ERROR ;
-
- strcpy( achPrinterData, pqp->piPrinter->pszDriverName ) ;
- achPrinterData[ strcspn(achPrinterData,".") ] = '\0' ;
-
- devop.pszDriverName = achPrinterData ;
- devop.pszLogAddress = pqp->piPrinter->pszName ;
-
- if( pqp->pdriv != NULL
- && strcmp( pqp->pdriv->szDeviceName, pqp->piPrinter->pDriverData->szDeviceName ) == 0 ) {
- devop.pdriv = pqp->pdriv ;
- }
- else devop.pdriv = pqp->piPrinter->pDriverData ;
-
- if( szPrintFile != NULL ) devop.pszLogAddress = szPrintFile ;
-
- // set data type to RAW
-
- devop.pszDataType = "PM_Q_RAW" ;
-
- // open device context
- if( lMode != 0L )
- lType = lMode ;
- else
- lType = (szPrintFile == NULL) ? OD_QUEUED: OD_DIRECT ;
-
- return DevOpenDC( hab, // WinQueryAnchorBlock( hwnd ),
- lType,
- "*",
- 4L,
- (PDEVOPENDATA) &devop,
- NULLHANDLE ) ;
- }
-
- int FindPrinter( char *szName, PPRQINFO3 piPrinter )
- /*
- ** Find a valid printer
- */
- {
- PPRQINFO3 pprq = NULL ;
- PDRIVDATA pdriv = NULL ;
- LONG np ;
-
- if( *szName && (strcmp( szName, piPrinter->pszName ) == 0) ) return 0 ;
- if( GetPrinters( &pprq , &np ) == 0 ) return 1 ;
- for( --np; np>=0; np-- ) {
- if( strcmp( szName, pprq[np].pszName ) == 0 ) {
- if( piPrinter->pDriverData != NULL ) free( piPrinter->pDriverData ) ;
- pdriv = malloc( pprq[np].pDriverData->cb ) ;
- memcpy( piPrinter, &pprq[np], sizeof( PRQINFO3 ) ) ;
- piPrinter->pDriverData = pdriv ;
- memcpy( pdriv, pprq[np].pDriverData, pprq[np].pDriverData->cb ) ;
- free( pprq ) ;
- return 0 ;
- }
- }
- memcpy( piPrinter, &pprq[0], sizeof( PRQINFO3 ) ) ;
- free( pprq ) ;
- return 0 ;
- }
-
- MRESULT EXPENTRY CancelPrintDlgProc ( HWND hwnd, ULONG usMsg, MPARAM mp1, MPARAM mp2 )
- /*
- ** Cancel printing dialog box proc
- */
- {
- switch ( usMsg ) {
-
- case WM_COMMAND :
- switch ( SHORT1FROMMP(mp1) ) {
- case DID_CANCEL:
- WinSendMsg( WinQueryWindow( hwnd, QW_OWNER ),
- WM_USER_PRINT_CANCEL,
- 0L,
- 0L ) ;
- WinDismissDlg( hwnd, 0 ) ;
- break ;
- default:
- break ;
- }
- default:
- break ;
- }
- /* fall through to the default control processing */
- return WinDefDlgProc ( hwnd , usMsg , mp1 , mp2 ) ;
- }
-
-
-